home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 748 / 748.xpi / content / accelimation.js next >
Text File  |  2010-02-11  |  4KB  |  124 lines

  1. //=====================================================================
  2. // Accel[erated] [an]imation object
  3. // change a property of an object over time in an accelerated fashion
  4. //=====================================================================
  5. // obj  : reference to the object whose property you'd like to animate
  6. // prop : property you would like to change eg: "left"
  7. // to   : final value of prop
  8. // time : time the animation should take to run
  9. // zip    : optional. specify the zippiness of the acceleration. pick a
  10. //          number between -1 and 1 where -1 is full decelerated, 1 is
  11. //          full accelerated, and 0 is linear (no acceleration). default
  12. //          is 0.
  13. // unit    : optional. specify the units for use with prop. default is
  14. //          "px".
  15. //=====================================================================
  16.  
  17. function Accelimation(obj, prop, to, time, zip, unit) {
  18.   if (typeof zip  == "undefined") zip  = 0;
  19.   if (typeof unit == "undefined") unit = "px";
  20.  
  21.   // NOTE: unlocalised string
  22.   if (zip > 2 || zip <= 0)
  23.     throw new Error("Illegal value for zip. Must be less than or equal to 2 and greater than 0.");
  24.  
  25.   this.obj = obj;
  26.   this.prop = prop;
  27.   this.x1 = to;
  28.   this.dt = time;
  29.   this.zip = zip;
  30.   this.unit = unit;
  31.  
  32.   this.x0 = parseInt(this.obj[this.prop]);
  33.   this.D = this.x1 - this.x0;
  34.   this.A = this.D / Math.abs(Math.pow(time, this.zip));
  35.   this.id = Accelimation.instances.length;
  36.   this.onend = null;
  37. }
  38.  
  39. //=====================================================================
  40. // public methods
  41. //=====================================================================
  42.  
  43. // after you create an accelimation, you call this to start it-a runnin'
  44. Accelimation.prototype.start = function() {
  45.   this.t0 = new Date().getTime();
  46.   this.t1 = this.t0 + this.dt;
  47.   var dx = this.x1 - this.x0;
  48.   Accelimation._add(this);
  49. };
  50.  
  51. // and if you need to stop it early for some reason...
  52. Accelimation.prototype.stop = function() {
  53.   Accelimation._remove(this);
  54. };
  55.  
  56.  
  57. //=====================================================================
  58. // private methods
  59. //=====================================================================
  60.  
  61. // paints one frame. gets called by Accelimation._paintAll.
  62. Accelimation.prototype._paint = function(time) {
  63.   if (time < this.t1) {
  64.     var elapsed = time - this.t0;
  65.     this.obj[this.prop] = Math.abs(Math.pow(elapsed, this.zip)) * this.A + this.x0 + this.unit;
  66.   }
  67.   else this._end();
  68. };
  69.  
  70. // ends the animation
  71. Accelimation.prototype._end = function() {
  72.   Accelimation._remove(this);
  73.   this.obj[this.prop] = this.x1 + this.unit;
  74.   this.onend();
  75. };
  76.  
  77. //=====================================================================
  78. // static methods (all private)
  79. //=====================================================================
  80.  
  81. // add a function to the list of ones to call periodically
  82. Accelimation._add = function(o) {
  83.   var index = this.instances.length;
  84.   this.instances[index] = o;
  85.   // if this is the first one, start the engine
  86.   if (this.instances.length == 1) {
  87.     this.timerID = window.setInterval("Accelimation._paintAll()", this.targetRes);
  88.   }
  89. };
  90.  
  91. // remove a function from the list
  92. Accelimation._remove = function(o) {
  93.   for (var i = 0; i < this.instances.length; i++) {
  94.     if (o == this.instances[i]) {
  95.       this.instances = this.instances.slice(0,i).concat( this.instances.slice(i+1) );
  96.       break;
  97.     }
  98.   }
  99.   // if that was the last one, stop the engine
  100.   if (this.instances.length == 0) {
  101.     window.clearInterval(this.timerID);
  102.     this.timerID = null;
  103.   }
  104. };
  105.  
  106. // "engine" - call each function in the list every so often
  107. Accelimation._paintAll = function() {
  108.   var now = new Date().getTime();
  109.   for (var i = 0; i < this.instances.length; i++) {
  110.     // small chance that this accelimation could get dropped in the queue in the middle
  111.     // of a run. That means that it could have a t0 greater than "now", which means that
  112.     // elapsed would be negative.
  113.     this.instances[i]._paint(Math.max(now, this.instances[i].t0));
  114.   }
  115. };
  116.  
  117. //=====================================================================
  118. // static properties
  119. //=====================================================================
  120.  
  121. Accelimation.instances = [];
  122. Accelimation.targetRes = 10;
  123. Accelimation.timerID = null;
  124.